package com.zyx.sparkdemo.core.rdd.operator.transform


import org.apache.spark.{SparkConf, SparkContext}

import scala.reflect.ClassTag


object Spark12_Transform_SortBy3 {
  def main(args: Array[String]): Unit = {
    val sparkConf = new SparkConf().setMaster("local[*]").setAppName("Operator")
    val sc = new SparkContext(sparkConf)

    val list = List(Person("jack1", 21), Person("marry", 30), Person("tom", 20), Person("jack1", 20))

    val rdd = sc.makeRDD(list, 2)

    // 自定义排序类, 实现Ordering, compare方法
    val myOrdering: Ordering[Person] = new Ordering[Person] {
      override def compare(x: Person, y: Person): Int = {
        val res = x.name.compareTo(y.name)
        if (res == 0) {
          x.age.compareTo(y.age)
        } else {
          res
        }
      }
    }


    /**
     * 对于自定义类型进行排序：
     *    1. 要排什么样的数据，就把数据封装为Tuple
     *    2. 柯里化函数传入一个比较器
     *    3. 让自定义类 extends  Comparable（java）
     *        Comparable : 实现了此接口的类是一个可以排序的类
     *        Scala中 自定义类 extends  Ordered， 实现compare方法！
     *    4. 提供一个Comparator[自定义类]
     *        提供一个比较器，可以比较Person类型的数据
     *        Scala: Ordering
     *        与 Comparable相比更灵活，非侵入！ Person 很清白，不需要实现任何接口（特质）
     */

    // 按照姓名升序, 年龄降序排列
    rdd
      // 映射成tuple
      /*.map(p => (p.name, p.age))
      .sortBy(p => p)(Ordering.Tuple2[String, Int](Ordering.String, Ordering.Int.reverse), ClassTag(classOf[(String, Int)]))*/
      .sortBy(p => p)(myOrdering, ClassTag(classOf[Person]))
      .coalesce(1)
      .collect
      .foreach(println)

    sc.stop()
  }
}

case class Person(name:String, age:Int)

// 样例类直接继承Ordered, 并重写compare方法
/*
case class Person(name:String, age:Int) extends Ordered[Person]{
  override def compare(that: Person): Int = {
    var res = this.name.compareTo(that.name)
    if (res == 0) {
      -this.age.compareTo(that.age)
    } else {
      res
    }
  }
}*/
